package org.sippr.rvt2ifc.utils;

import org.springframework.stereotype.Component;

@Component
public class SnowflakeIdGenerator {
    // 起始时间戳（通常设置为系统开始时间或某个固定时间）
    private static final long START_EPOCH = 1640966400000L; // 2022-01-01 00:00:00

    private static final long SEQUENCE_BITS = 12L;  // 序列号占用的位数
    private static final long MACHINE_BITS = 10L;   // 机器 ID 占用的位数

    private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS); // 4095
    private static final long MAX_MACHINE_ID = ~(-1L << MACHINE_BITS); // 1023

    private static final long MACHINE_SHIFT = SEQUENCE_BITS;          // 12 位
    private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + MACHINE_BITS; // 22 位

    private static long sequence = 0L; // 当前毫秒内的序列号
    private static long lastTimestamp = -1L; // 上一次生成 ID 的时间戳


    public synchronized static String nextId() {
        long currentTimestamp = System.currentTimeMillis();

        // 如果当前时间小于上次生成时间，抛出异常
        if (currentTimestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards. Refusing to generate ID.");
        }

        if (currentTimestamp == lastTimestamp) {
            // 同一毫秒内，增加序列号
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0) {
                // 序列号耗尽，等待下一毫秒
                currentTimestamp = waitForNextMillis(currentTimestamp);
            }
        } else {
            // 不同毫秒，重置序列号
            sequence = 0L;
        }

        lastTimestamp = currentTimestamp;

        // 组合生成 ID
        // 当前机器 ID
        long machineId = 1;
        long uuid = ((currentTimestamp - START_EPOCH) << TIMESTAMP_SHIFT) |
                (machineId << MACHINE_SHIFT) |
                sequence;
        return String.valueOf(uuid);
    }

    private static long waitForNextMillis(long currentTimestamp) {
        while (currentTimestamp <= lastTimestamp) {
            currentTimestamp = System.currentTimeMillis();
        }
        return currentTimestamp;
    }

}
